#ifndef UDNET_H_
#define UDNET_H_
#include<iostream>
#include"Graph.h"
using namespace std;

template<typename Type>
class UDNet: public Graph{

public:
	template<typename Type>
	friend ostream &operator<<(ostream &output, UDNet<Type> &UDN);
	template<typename Type>
	friend istream &operator>>(istream &input, UDNet<Type> &UDN);


	UDNet(int vexnum = 0, int arcnum = 0);
	~UDNet();

	Status setPtrtoMatrix(Type*);
	Type *getMatrix();

private:
	Type *m_pMatrix;
};


template<typename Type>
ostream &operator<<(ostream &output, UDNet<Type> &UDN) {
	Type* ptr = UDN.getMatrix();
	int vexnum = UDN.getVexnum();
	for (int i = 0; i < vexnum * vexnum; ++i) {
		output << ptr[i] << " ";
		if ((i + 1) % vexnum == 0) {
			output << endl;
		}
	}
	return output;
}

template<typename Type>
istream &operator>>(istream &input, UDNet<Type> &UDN) {
	delete UDN.getMatrix();
	cout << "please input the number of vertex and arc" << endl;
	int vexnum, arcnum;
	do {
		input >> vexnum >> arcnum;
		if (vexnum < 0 || arcnum < 0) {
			cout << "Illegal! please input again" << endl;
		}
		else
			break;
	} while (1);

	UDN.setVexnum(vexnum);
	UDN.setArcnum(arcnum);
	UDN.setGkind(UDNE);

	Type* ptr = new Type[vexnum*vexnum];
	if (ptr == nullptr) {
		perror("Failed to allocate memory!");
		exit(EXIT_FAILURE);
	}
	for (int i = 0; i < vexnum * vexnum; ++i) {
		ptr[i] = 0;
	}

	UDN.setPtrtoMatrix(ptr);
	cout << "Please input arcs and its weight,like this: 1 2 5;" << endl;
	cout << "it means that there is an arc between vex 1 and vex 2 and its weitht is 5" << endl;
	int num = arcnum;
	int v1, v2;
	Type w;
	while (num--) {
		input >> v1 >> v2 >> w;
		--v1; --v2;
		if (v1 < 0 || v2 < 0 || v1 >= vexnum || v2 >= vexnum) {
			cout << "illegal! please input again!" << endl;
			++num;
		}
		ptr[v1*vexnum + v2] = w;
		ptr[v2*vexnum + v1] = w;
	}
	return input;
}

template<typename Type>
UDNet<Type>::UDNet(int vexnum, int arcnum){
	this->setVexnum(vexnum);
	this->setArcnum(arcnum);
	this->setGkind(UDNE);

	Type* ptr = new Type[vexnum*vexnum];
	if (ptr == nullptr) {
		perror("Failed to allocate memory!");
		exit(EXIT_FAILURE);
	}
	for (int i = 0; i < vexnum * vexnum; ++i) {
		ptr[i] = -1;
	}

	this->setPtrtoMatrix(ptr);
	cout << "Please input arcs and its weight,like this: 1 2 5;" << endl;
	cout <<	"it means that there is an arc between vex 1 and vex 2 and its weitht is 5" << endl;
	int num = arcnum;
	int v1, v2;
	Type w;
	while (num--) {
		cin >> v1 >> v2 >> w;
		--v1; --v2;
		if (v1 < 0 || v2 < 0 || v1 >= vexnum || v2 >= vexnum) {
			cout << "illegal! please input again!" << endl;
			++num;
		}
		ptr[v1*vexnum + v2] = w;
		ptr[v2*vexnum + v1] = w;
	}
}

template<typename Type>
UDNet<Type>::~UDNet(){
	delete this->getMatrix();
	this->setPtrtoMatrix(nullptr);
}

template<typename Type>
inline Status UDNet<Type>::setPtrtoMatrix(Type *matrix){
	m_pMatrix = matrix;
	return OK;
}

template<typename Type>
inline Type * UDNet<Type>::getMatrix(){
	return m_pMatrix;
}


#endif